define(
["entity/Ground"],
function(Ground) {
    function _latToTileY(lat, zoom) {
        return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) +
            1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom)));
    }

    function _lonToTileX(lon, zoom) {
        return (Math.floor((lon+180)/360*Math.pow(2,zoom)));
    }

    function _tileYToLat(y, z) {
        var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
        return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
    }

    function _tileXToLon(x, z) {
        return (x/Math.pow(2,z)*360-180);
    }

    function _getTileUrl(x, y, zoom) {
        return "http://a.tile.openstreetmap.org/" +
            zoom + "/" + x + "/" + y + ".png";
    }

    function _buildGrounds(data, convF, systemMgr, out) {
        data.forEach(function(val){
            out.push(
                Ground.create().init(val, systemMgr)
            );
        });
    }

    return {
        createGrounds: function(systemMgr, src, convF, out) {
            var bounds = $(src).find("bounds")[0];
            var minLat = +$(bounds).attr("minlat");
            var minLon = +$(bounds).attr("minlon");
            var maxLat = +$(bounds).attr("maxlat");
            var maxLon = +$(bounds).attr("maxlon");

            var zoom = 18;
            var minTileY = _latToTileY(minLat, zoom);
            var minTileX = _lonToTileX(minLon, zoom);
            var maxTileY = _latToTileY(maxLat, zoom);
            var maxTileX = _lonToTileX(maxLon, zoom);

            var temp = [];
            for(var i = minTileX; i <= maxTileX; ++i) {
                for(var j = minTileY; j >= maxTileY; --j) {
                    temp.push({
                        posY: convF.lonToMeter(_tileXToLon(i, zoom)),
                        posX: convF.latToMeter(_tileYToLat(j+1, zoom)),
                        maxY: convF.lonToMeter(_tileXToLon(i+1, zoom)),
                        maxX: convF.latToMeter(_tileYToLat(j, zoom)),
                        imgUrl: _getTileUrl(i, j, zoom)
                    });
                }
            }

            _buildGrounds(temp, convF, systemMgr, out);
        }
    };
});